Introduction
In this project, we’re examining inspection scores for restaurants in and around Austin, Texas, from 2014 through early 2017. Scores are determined through routine inspections, usually conducted twice a year. If a score lower than 70 is recorded in a yearly inspection, the restaurant will be subjected to one or more followup visits to ensure a return to compliance. All of our restaurant inspection records include geographical information in the form of zip codes, allowing the use of additional datasets to further explore the data. Visit https://data.world/kvaughn/s-17-dv-project-6 to explore our datasets, or see below for the visualizations we’ve made of the data.
R Configuration
Below we display our sessionInfo().
R version 3.3.2 (2016-10-31)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X Yosemite 10.10.5
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] readr_1.1.0 data.world_0.1.2 dplyr_0.5.0 quantreg_5.33
[5] SparseM_1.77 plotly_4.6.0 ggplot2_2.2.1.9000 leaflet_1.1.0
[9] DT_0.2 shinydashboard_0.5.3 shiny_1.0.0
loaded via a namespace (and not attached):
[1] Rcpp_0.12.10 plyr_1.8.4 base64enc_0.1-3 bitops_1.0-6 tools_3.3.2
[6] digest_0.6.12 evaluate_0.10 jsonlite_1.3 tibble_1.3.0 gtable_0.2.0
[11] viridisLite_0.2.0 lattice_0.20-34 Matrix_1.2-7.1 DBI_0.5-1 crosstalk_1.0.0
[16] curl_2.3 yaml_2.1.14 knitr_1.15.1 stringr_1.1.0 httr_1.2.1
[21] hms_0.3 htmlwidgets_0.8 MatrixModels_0.4-1 rprojroot_1.2 grid_3.3.2
[26] R6_2.2.0 rmarkdown_1.3 RJSONIO_1.3-0 purrr_0.2.2 tidyr_0.6.1
[31] magrittr_1.5 backports_1.0.5 scales_0.4.1 htmltools_0.3.5 rsconnect_0.7
[36] assertthat_0.1 mime_0.5 xtable_1.8-2 colorspace_1.3-2 httpuv_1.3.3
[41] labeling_0.3 stringi_1.1.2 RCurl_1.95-4.8 lazyeval_0.2.0 munsell_0.4.3
Visualizations
Visualizations using Shiny in R
The screenshots and descriptions below are based on our interactive visualization app, accessible at https://kvaughn.shinyapps.io/restaurant_inspection/.
Boxplot Visualization using Shiny in R
One low score does not indicate a systemic problem with a restaurant’s cleanliness; before judging a restaurant with a low score, it behooves us to consider the other scores it has received. This boxplot allows the user to do just that. First select a cutoof point for scores, then choose a zipcode to see all restaurants that have scored below that level at least one. Each restaurant’s scores will display, giving the user an idea of whether the low score was a fluke or a sign of problems.
Histogram Visualization using Shiny in R
Scatterplot Visualization using Shiny in R
Safety Index
This visualization starts with a somewhat-arbitrary KPI, the “Safety Index,” that takes into account both the average score and the lowest inspection score received for a given zip code in a given year. A high Safety Index indicates both a high average score and a high minimum score. Set the parameters however you like (3 and 8 are reasonable defaults) and check the crosstab to see each zip code’s ratings over the four-year period.
Lowest Inspection Scores
This visualization allows the user to set an arbitrary cutoff point as an aid for identifying low inspection scores. The default value, 70, is the cutoff for restaurant inspections; lower scores will trigger a reinspection. After selecting a parameter using the slider and requesting data, the user can select the “Crosstab” tab to see which zip codes and years had unacceptably low inspection scores.
People per Restaurant
Austin is a fast-growing city, and our restaurant scene is currently booming as well. This visualization allows a user to see where the density of restaurants compared to population is highest. Using a public population dataset generated by the US Census, we can find the number of people per restaurant in a given zip code; as more restaurants are added (or fail), the people-per-restaurant number changes. The default values highlight the density of restaurants in 78701, which is downtown Austin.
Barchart Visualizations using Shiny in R
These visualizations are also accessible at https://kvaughn.shinyapps.io/restaurant_inspection/
Scores by Zip Code
Barcharts can be a good way to quickly identify trends visually. In this visualization, the user can create a set of zip codes of interest, then see each zipcode’s average score per year over the three or four years contained in the dataset.
Transit stops and restaurant density
Capital Metro, the Austin-area transit service, has made its data freely available for public download. By importing this data into geographic information software (ArcGIS) and overlaying the coordinates of transit stops on a shapefile of regional zip codes, we were able to count the number of transit stops per zip code. In this bar chart, we’re examining the relationship between transit density and restaurant density. Use the slider to select zip codes with more than the minimum number of transit stops, then compare the number of restaurants in these zip codes to the average number of restaurants per zip code throughout the region. The blue line is the calculated average for all of the selected zip codes, and the red is the grand average for all of the zipcodes in the Greater Austin area.
Nonnative residents and restaurant density
Would we expect zip codes with comparatively large numbers of nonnative (naturalized-citizen or noncitizen) residents to have more or fewer restaurants, on average, than zip codes with lower percentages of nonnative residents? This barchart allows the user to select a minimum percentage of nonnative residents per zip code, then shows the number of restaurants in that zip code and the average number of restaurants per zip code for all of the qualifying zip codes. This average can be compared to the grand average throughout the greater Austin area, shown in red.
LS0tCnRpdGxlOiAiQXVzdGluIFJlc3RhcmFudCBJbnNwZWN0aW9ucyIKYXV0aG9yOiAiPGNlbnRlcj48Yj5NYXJjdXMgTWFydGluZXogYW5kIEthdGUgVmF1Z2huPC9iPjwvY2VudGVyPiIKZGF0ZTogIjxjZW50ZXI+TWF5IDIsIDIwMTc8L2NlbnRlcj4iCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKLS0tCgojKipJbnRyb2R1Y3Rpb24qKgogSW4gdGhpcyBwcm9qZWN0LCB3ZSdyZSBleGFtaW5pbmcgaW5zcGVjdGlvbiBzY29yZXMgZm9yIHJlc3RhdXJhbnRzIGluIGFuZCBhcm91bmQgQXVzdGluLCBUZXhhcywgZnJvbSAyMDE0IHRocm91Z2ggZWFybHkgMjAxNy4gIFNjb3JlcyBhcmUgZGV0ZXJtaW5lZCB0aHJvdWdoIHJvdXRpbmUgaW5zcGVjdGlvbnMsIHVzdWFsbHkgY29uZHVjdGVkIHR3aWNlIGEgeWVhci4gIElmIGEgc2NvcmUgbG93ZXIgdGhhbiA3MCBpcyByZWNvcmRlZCBpbiBhIHllYXJseSBpbnNwZWN0aW9uLCB0aGUgcmVzdGF1cmFudCB3aWxsIGJlIHN1YmplY3RlZCB0byBvbmUgb3IgbW9yZSBmb2xsb3d1cCB2aXNpdHMgdG8gZW5zdXJlIGEgcmV0dXJuIHRvIGNvbXBsaWFuY2UuICBBbGwgb2Ygb3VyIHJlc3RhdXJhbnQgaW5zcGVjdGlvbiByZWNvcmRzIGluY2x1ZGUgZ2VvZ3JhcGhpY2FsIGluZm9ybWF0aW9uIGluIHRoZSBmb3JtIG9mIHppcCBjb2RlcywgYWxsb3dpbmcgdGhlIHVzZSBvZiBhZGRpdGlvbmFsIGRhdGFzZXRzIHRvIGZ1cnRoZXIgZXhwbG9yZSB0aGUgZGF0YS4gIFZpc2l0IGh0dHBzOi8vZGF0YS53b3JsZC9rdmF1Z2huL3MtMTctZHYtcHJvamVjdC02IHRvIGV4cGxvcmUgb3VyIGRhdGFzZXRzLCBvciBzZWUgYmVsb3cgZm9yIHRoZSB2aXN1YWxpemF0aW9ucyB3ZSd2ZSBtYWRlIG9mIHRoZSBkYXRhLgoKIyMqKlIgQ29uZmlndXJhdGlvbioqCkJlbG93IHdlIGRpc3BsYXkgb3VyIHNlc3Npb25JbmZvKCkuCgpgYGB7ciBTZXNzaW9uSW5mbywgZWNobz1GQUxTRX0gCnNlc3Npb25JbmZvKHBhY2thZ2U9TlVMTCkKYGBgCgojKipUaGUgRGF0YSoqClRoZSByZXN0YXVyYW50IGluc3BlY3Rpb24gZGF0YXNldCB3YXMgcHJvdmlkZWQgdGhyb3VnaCB0aGUgQ2l0eSBvZiBBdXN0aW4ncyBPcGVuIERhdGEgUG9ydGFsLCBodHRwczovL2RhdGEuYXVzdGludGV4YXMuZ292Ly4gIFRoaXMgZnJlZSBkb3dubG9hZCBpcyBhdmFpbGFibGUgaW4gbXVsdGlwbGUgZm9ybWF0cyBhdCBodHRwczovL2RhdGEuYXVzdGludGV4YXMuZ292L0hlYWx0aC9SZXN0YXVyYW50LUluc3BlY3Rpb24tU2NvcmVzL3V0aHctYTdpaC4gIEZvciB0aGlzIHByb2plY3QsIHdlIGRvd25sb2FkZWQgYSBDU1YgZmlsZSBhbmQgY2xlYW5lZCBpdCB1c2luZyB0aGUgRXh0cmFjdC1UcmFuc2xhdGUtTG9hZCBwcm9jZWR1cmUgb3V0bGluZWQgYmVsb3cuCgojKipFeHRyYWN0LVRyYW5zbGF0ZS1Mb2FkIChFVEwpKioKVGhlIGRhdGFzZXQgd2UgcmVjZWl2ZWQgbmVlZGVkIHNvbWUgY2xlYW5pbmcsIGFzIGl0IHdhcyB1bnJlYWRhYmxlIHRvIFRhYmxlYXUgaW4gaXRzIG9yaWdpbmFsIENTViBmb3JtYXR0aW5nLiAgV2UgdXNlZCB0aGUgRXh0cmFjdC1UcmFuc2xhdGUtTG9hZCBtZXRob2QgZGlzY3Vzc2VkIGluIGNsYXNzLCBhbmQgYnVpbHQgYW4gUiBzY3JpcHQgZm91bmQgYXQgIi4uLzAxIERhdGEvRVRMUmVzdGF1cmFudC5SIiAgV2UgYWxzbyBjbGVhbmVkIHVwIHRoZSBqb2luIHF1ZXJ5IHVzZWQgaW4gb3VyIFRhYmxlYXUgdmlzdWFsaXphdGlvbnM7IGl0IGNhbiBiZSBmb3VuZCBhdCAiLi4vMDEgRGF0YS9FVExRdWVyeS5SIiAgSWYgeW91J2QgbGlrZSB0byBmb2xsb3cgYWxvbmcsIGhlcmUncyBob3cgd2UgcHJvY2Vzc2VkIHRoZSByZXN0YXVyYW50IGluc3BlY3Rpb24gZGF0YToKCiMjKlN0ZXAtQnktU3RlcCBJbnN0cnVjdGlvbnMqCioqRmlyc3QsIGRvd25sb2FkIHRoZSB1bmNsZWFuZWQgQ1NWOiBodHRwczovL2RhdGEuYXVzdGludGV4YXMuZ292L2FwaS92aWV3cy9lY212LTl4eGkvcm93cy5jc3Y/YWNjZXNzVHlwZT1ET1dOTE9BRC4gUHJlcGVuZCAiUHJlRVRMXyIgdG8gdGhlIGZpbGUgbmFtZSwgYW5kIHB1dCBpdCBpbiBhIGZvbGRlciBjYWxsZWQgQ1NWcyBpbiB0aGUgc2FtZSBkaXJlY3RvcnkgYXMgdGhpcyBwcm9qZWN0IChzMTdkdnByb2plY3Q1LXZhdWdobi1jYW5uYXRhLW1hcnRpbmV6KS4qKgoKIyMjKlN0ZXAgMTogU2V0IHVwIHRoZSBlbnZpcm9ubWVudCoKTm90ZSB0aGF0IHdlIGhhdmUgb25lIGNvbHVtbiBvZiBudW1lcmljIGRhdGEgKCJTY29yZSIpLCBvbmUgY29sdW1uIG9mIGRhdGVzICgiSW5zcGVjdGlvbiBEYXRlIiksIHRocmVlIGNvbHVtbnMgb2Ygc3RyaW5ncyAoIlJlc3RhdXJhbnQgTmFtZSIsICJBZGRyZXNzIiwgYW5kICJQcm9jZXNzIERlc2NyaXB0aW9uIiksIGFuZCB0d28gY29sdW1ucyBvZiBudW1lcmljIGRhdGEgdXNlZCBjYXRlZ29yaWNhbGx5ICgiWmlwIENvZGUiIGFuZCAiRmFjaWxpdHkgSUQiKS4gIEZvciB0aGUgc2FrZSBvZiBlYXNlIG9mIHVzZSwgdGhlc2UgbGFzdCB0d28gY29sdW1ucyB3aWxsIGJlIHRyZWF0ZWQgYXMgc3RyaW5ncy4KYGBge3IgZXRsMX0KIyBTZXQgd29ya2luZyBkaXJlY3RvcnkKc2V0d2QoIn4vczE3ZHZmaW5hbHByb2plY3QtdmF1Z2huLWNhbm5hdGEtbWFydGluZXotMS8wMCBEb2NzIikKCiMgU2V0IGZpbGVwYXRoCmZpbGVfcGF0aCA9ICIuLi8uLi9DU1ZzL1ByZUVUTF9SZXN0YXVyYW50X0luc3BlY3Rpb25fU2NvcmVzLmNzdiIKCiMgQ3JlYXRlIGRhdGFmcmFtZSBmcm9tIG9yaWdpbmFsIENTVgpkZiA8LSByZWFkLmNzdihmaWxlX3BhdGgsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKCiMgU3RhbmRhcmRpemUgY29sdW1uIG5hbWVzCm5hbWVzKGRmKSA8LSBnc3ViKCJcXC4rIiwgIiAiLCBuYW1lcyhkZikpCgojIFByaW50IGNvbHVtbiBuYW1lcyBhbmQgdHlwZXMKc3RyKGRmKQpgYGAKCiMjIypTdGVwIDI6IENvbGxlY3QgY29sdW1ucyBieSB0eXBlKgpXZSd2ZSBncm91cGVkIHRoZSBkYXRlIGNvbHVtbiBzZXBhcmF0ZWx5IGZyb20gbWVhc3VyZXMgYW5kIGRpbWVuc2lvbnM7IHdoaWxlIFRhYmxlYXUgd2lsbCByZWNvZ25pemUgdGhlc2UgZGF0YSBhcyBkYXRlcywgaXQgc2VlbXMgcHJ1ZGVudCB0byByZWNsYXNzaWZ5IHRoZW0gaW50byBhIHN0YW5kYXJkaXplZCBmb3JtYXQuCmBgYHtyIGV0bDJ9CiMgU2VsZWN0IHN0cmluZyBkYXRhIGFzICdkaW1lbnNpb25zJwpkaW1lbnNpb25zIDwtIGMoIlJlc3RhdXJhbnQgTmFtZSIsICJaaXAgQ29kZSIsICJBZGRyZXNzIiwgIlByb2Nlc3MgRGVzY3JpcHRpb24iLCAiRmFjaWxpdHkgSUQiKQoKIyBTZWxlY3QgZGF0ZXMgYXMgJ2RhdGVzJwpkYXRlcyA8LSBjKCJJbnNwZWN0aW9uIERhdGUiKQoKIyBTZWxlY3QgYWxsIHJlbWFpbmluZyBkYXRhIGFzICdtZWFzdXJlcycKbWVhc3VyZXMgPC0gc2V0ZGlmZihuYW1lcyhkZiksIHVuaW9uKGRpbWVuc2lvbnMsIGRhdGVzKSkKCmBgYAoKIyMjKlN0ZXAgMzogUmVtb3ZlIHNwZWNpYWwgY2hhcmFjdGVycyoKSGVyZSB3ZSByZW1vdmUgc3BlY2lhbCBjaGFyYWN0ZXJzIGZyb20gYWxsIG9mIG91ciBkYXRhLiAgVGhlc2UgY2hhcmFjdGVycyBjYW4gc2VydmUgbm8gcHVycG9zZSBpbiB0aGUgZGF0YSwgYW5kIG1pZ2h0IGNhdXNlIHByb2JsZW1zIGluIHRoZSBhbmFseXNpcyBwcm9jZXNzLiAgVG8gaW1wcm92ZSByZWFkYWJpbGl0eSwgc3BlY2lhbCBjaGFyYWN0ZXJzIGhhdmUgYmVlbiByZXBsYWNlZCBieSBzcGFjZXMuCmBgYHtyIGV0bDN9CiMgR2V0IHJpZCBvZiBzcGVjaWFsIGNoYXJhY3RlcnMgaW4gZWFjaCBjb2x1bW4uCmZvcihuIGluIG5hbWVzKGRmKSkgewogIGRmW25dIDwtIGRhdGEuZnJhbWUobGFwcGx5KGRmW25dLCBnc3ViLCBwYXR0ZXJuPSJbXiAtfl0iLHJlcGxhY2VtZW50PSAiICIpLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCn0KYGBgCgojIyMqU3RlcCA0OiBNb2RpZnkgcmVjb3JkcyBpbiBkaW1lbnNpb25zKgpOb3cgd2UgZ28gdGhyb3VnaCBhbGwgb2YgdGhlIGNoYXJhY3Rlci1iYXNlZCBjb2x1bW5zIChncm91cGVkIGFzIGRpbWVuc2lvbnMpIGFuZCByZW1vdmUgdHJvdWJsZXNvbWUgY2hhcmFjdGVycy4gIEFtcGVyc2FuZHMgYXJlIHJlcGxhY2VkIHdpdGggImFuZCIsIHNlbWljb2xvbnMgYXJlIHJlcGxhY2VkIHdpdGggY29sb25zLCBhbmQgc2luZ2xlLSBhbmQgZG91YmxlLXF1b3RlcyBhcmUgcmVtb3ZlZCBvdXRyaWdodC4gIERhdGEgb2YgTkEgKG51bGwpIGlzIHJlcGxhY2VkIHdpdGggYW4gZW1wdHkgc3RyaW5nLgpgYGB7ciBldGw0fQojIFRoaXMgZnVuY3Rpb24gd2lsbCByZXBsYWNlIE5BIGRhdGEgd2l0aCBhbiBlbXB0eSBzdHJpbmcKbmEyZW1wdHlTdHJpbmcgPC0gZnVuY3Rpb24gKHgpIHsKICB4W2lzLm5hKHgpXSA8LSAiIgogIHJldHVybih4KQp9CiMgV2UnbGwgYXBwbHkgdGhpcyB0byBhbGwgY29sdW1ucyBncm91cGVkIGFzIGRpbWVuc2lvbnMKaWYoIGxlbmd0aChkaW1lbnNpb25zKSA+IDApIHsKICBmb3IoZCBpbiBkaW1lbnNpb25zKSB7CiAgICAjIENoYW5nZSBOQSB0byB0aGUgZW1wdHkgc3RyaW5nLgogICAgZGZbZF0gPC0gZGF0YS5mcmFtZShsYXBwbHkoZGZbZF0sIG5hMmVtcHR5U3RyaW5nKSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQogICAgIyBHZXQgcmlkIG9mICIgYW5kICcgaW4gZGltZW5zaW9ucy4KICAgIGRmW2RdIDwtIGRhdGEuZnJhbWUobGFwcGx5KGRmW2RdLCBnc3ViLCBwYXR0ZXJuPSJbXCInXSIscmVwbGFjZW1lbnQ9ICIiKSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQogICAgIyBDaGFuZ2UgJiB0byBhbmQgaW4gZGltZW5zaW9ucy4KICAgIGRmW2RdIDwtIGRhdGEuZnJhbWUobGFwcGx5KGRmW2RdLCBnc3ViLCBwYXR0ZXJuPSImIixyZXBsYWNlbWVudD0gIiBhbmQgIiksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKICAgICMgQ2hhbmdlIDogdG8gOyBpbiBkaW1lbnNpb25zLgogICAgZGZbZF0gPC0gZGF0YS5mcmFtZShsYXBwbHkoZGZbZF0sIGdzdWIsIHBhdHRlcm49IjoiLHJlcGxhY2VtZW50PSAiOyIpLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCiAgfQp9CgpgYGAKCiMjIypTdGVwIDU6IE1vZGlmeSBkYXRlcyoKSGVyZSB3ZSBlbnN1cmUgdGhhdCBkYXRlcyBhcmUgZm9ybWF0dGVkIGNvcnJlY3RseS4KYGBge3IgZXRsNX0KaWYoIGxlbmd0aChkYXRlcykgPiAxIHx8ICEgaXMubmEoZGF0ZXMpKSB7CiAgZm9yKHkgaW4gZGF0ZXMpIHsKICAgICMgRm9ybWF0IGFzIGRhdGVzCiAgICBkZlt5XSA8LSBkYXRhLmZyYW1lKGxhcHBseShkZlt5XSwgZnVuY3Rpb24oeSkgYXMuRGF0ZSh5LCBmb3JtYXQgPSAiJW0vJWQvJXkiKSksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKICB9Cn0KYGBgCgojIyMqU3RlcCA2OiBNb2RpZnkgbWVhc3VyZXMqCk5vdyB3ZSB0YWtlIGFsbCBvZiB0aGUgbm9uLW51bWVyaWMgY2hhcmFjdGVycyBvdXQgb2Ygb3VyIG1lYXN1cmVzLgpgYGB7ciBldGw2fQpuYTJ6ZXJvIDwtIGZ1bmN0aW9uICh4KSB7CiAgeFtpcy5uYSh4KV0gPC0gMAogIHJldHVybih4KQp9CiMgR2V0IHJpZCBvZiBhbGwgY2hhcmFjdGVycyBpbiBtZWFzdXJlcyBleGNlcHQgZm9yIG51bWJlcnMsIHRoZSAtIHNpZ24sIGFuZCBwZXJpb2QuZGltZW5zaW9ucywgYW5kIGNoYW5nZSBOQSB0byAwLgppZihsZW5ndGgobWVhc3VyZXMpID4gMSB8fCAhIGlzLm5hKG1lYXN1cmVzKSkgewogIGZvcihtIGluIG1lYXN1cmVzKSB7CiAgICBkZlttXSA8LSBkYXRhLmZyYW1lKGxhcHBseShkZlttXSwgZ3N1YiwgcGF0dGVybj0iW14tLS4wLTldIixyZXBsYWNlbWVudD0iIiksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKICAgIGRmW21dIDwtIGRhdGEuZnJhbWUobGFwcGx5KGRmW21dLCBuYTJ6ZXJvKSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQogICAgZGZbbV0gPC0gZGF0YS5mcmFtZShsYXBwbHkoZGZbbV0sIGZ1bmN0aW9uKG0pIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG0pKSkpICMgVGhpcyBpcyBuZWVkZWQgdG8gdHVybiBtZWFzdXJlcyBiYWNrIHRvIG51bWVyaWMgYmVjYXVzZSBnc3ViIHR1cm5zIHRoZW0gaW50byBzdHJpbmdzLgogIH0KfQpgYGAKCiMjIypTdGVwIDc6IER1bW15IGNoZWNrKgpBbHdheXMgYSB1c2VmdWwgdGhpbmcuICBMZXQncyBsb29rIGF0IG91ciBkYXRhIGFuZCBzZWUgd2hhdCB3ZSd2ZSBnb3QuICBXZSdyZSBleHBlY3RpbmcgYWxsIGRhdGEgdG8gYmUgaW4gY2hhcmFjdGVyIGZvcm0gZXhjZXB0ICJTY29yZSIsIHdoaWNoIHdpbGwgYmUgbnVtZXJpYywgYW5kIG91ciBkYXRlIGNvbHVtbiBuYW1lZCAiSW5zcGVjdGlvbiBEYXRlIi4KYGBge3IgZXRsN30KIyBUYWtlIGEgbG9vayBhbmQgbWFrZSBzdXJlIGl0J3Mgd2hhdCB5b3UgdGhpbmsgaXQgc2hvdWxkIGJlOgpwcmludChzdW1tYXJ5KGRmKSkKYGBgCgojIyMqU3RlcCA4OiBXcml0ZSB0byBhIG5ldyBmaWxlKgpPdXIgZGF0YSBsb29rcyBnb29kLCBhbmQgd2UgbmVlZCB0byB3cml0ZSBpdCB0byBhIG5ldyBmaWxlLgpgYGB7ciBldGw4fQojIE5vdyB3cml0ZSBpdCB0byBhIG5ldyBjbGVhbiBmaWxlLgp3cml0ZS5jc3YoZGYsIGdzdWIoIlByZUVUTF8iLCAiIiwgZmlsZV9wYXRoKSwgcm93Lm5hbWVzPUZBTFNFLCBuYSA9ICIiKQpgYGAKCiMqKlZpc3VhbGl6YXRpb25zKioKCiMjKipDcm9zc3RhYi1yZWxhdGVkIFZpc3VhbGl6YXRpb25zIHVzaW5nIFRhYmxlYXUqKgpCZWxvdyB5b3Ugd2lsbCBmaW5kIHRoZSB2aXN1YWxpemF0aW9ucyB3ZSBjcmVhdGVkIHVzaW5nIFRhYmxlYXUuIEVhY2ggdmlzdWFsaXphdGlvbiBpcyBvbmx5IGEgZnJhY3Rpb24gb2YgdGhlIGluZm9ybWF0aW9uIHRoYXQgY2FuIGJlIHZpZXdlZCBpbiBUYWJsZWF1LCBhcyB0aGVzZSBjcm9zc3RhYnMgY2Fubm90IHNob3djYXNlIGFsbCB0aGUgaW5mb3JtYXRpb24gYXZhaWxhYmxlIGF0IG9uY2UuICBPdXIgVGFibGVhdSB3b3JrYm9vayBpcyBpbmNsdWRlZCBpbiBvdXIgcmVwb3NpdG9yeSBpbiB0aGUgZm9sZGVyIDAxIERhdGEuCgojIyMqSW5zcGVjdGlvbiBTY29yZXMsIEFyZWEsIGFuZCBJbmNvbWUqClRoaXMgY3Jvc3N0YWIgc2hvd3MgYnkgeWVhciBhbmQgemlwY29kZSAoaW4gQXVzdGluKSwgdGhlIGF2ZXJhZ2UgcmVzdGF1cmFudCBpbnNwZWN0aW9uIHNjb3JlLiBUaGUgY3Jvc3N0YWIgaXMgY29sb3JlZCBieSB0aGUgcGVyY2VudGFnZSBvZiBob3VzZWhvbGRzIGluIGVhY2ggYXJlYSB1bmRlciB0aGUgbmF0aW9uYWwgcG92ZXJ0eSBsaW5lIChwdWxsZWQgZnJvbSBVUyBDZW5zdXMgZGF0YSkuIEFzIGlzIGV2aWRlbnQsIGF2ZXJhZ2Ugc2NvcmVzIHJlbWFpbiByZWxhdGl2ZWx5IGhpZ2ggYWNyb3NzIHBvdmVydHkgbGV2ZWxzIGFuZCB6aXBjb2Rlcy4gSW4gVGFibGVhdSB5b3UgYXJlIGFibGUgdG8gY3ljbGUgdGhyb3VnaCB6aXBjb2RlcyBpbiB0aGUgd2VzdGVybiBvciBlYXN0ZXJuIGhhbGYgb2YgdGhlIGdyZWF0ZXIgQXVzdGluIGFyZWEuIEV2ZW4gYXQgdGhpcyBsZXZlbCwgYXZlcmFnZSBzY29yZXMgcmVtYWluIHNpbWlsYXIuIFRoZXJlIGFyZSBtb3JlIGF2ZXJhZ2Ugc2NvcmVzIGJlbG93IDkwIGluIHRoZSBlYXN0ZXJuIHNlY3Rpb24sIGJ1dCB0aGlzIGlzIGxpa2VseSBub3Qgc2lnbmlmaWNhbnQuCgo8Y2VudGVyPiFbVGFibGVhdTogU2NvcmVzIGJ5IEluY29tZSBhbmQgQXJlYV0oLi4vMDMgVmlzdWFsaXphdGlvbnMvQ3Jvc3N0YWJBdmVyYWdlU2NvcmVieVBvdmVydHlMZXZlbC5wbmcpPC9jZW50ZXI+CgpJdCBpcyBwb3NzaWJsZSB0aGlzIGlzIHVuaXF1ZSB0byBBdXN0aW4sIGFuZCBtYXkgYmUgYSBjb25zZXF1ZW5jZSBvZiBzdHJpbmdlbnQgZm9vZCBzYWZldHkgY29kZSBpbiB0aGVzZSBhcmVhcy4gRnVydGhlciBhbmFseXNpcyB3b3VsZCBuZWVkIHRvIGJlIGRvbmUgdG8gc2VlIGlmIHRoZXNlIGNvcnJlbGF0aW9ucyBhcmUgdHJ1ZSBlbHNld2hlcmUgaW4gdGhlIFVuaXRlZCBTdGF0ZXMuCgojIyMqQXZlcmFnZSBJbnNwZWN0aW9uIFNjb3JlcyBHZW9ncmFwaGljYWxseSoKQXMgY2FuIGJlIHNlZW4sIHRoaXMgdmlzdWFsaXphdGlvbiBkaXNwbGF5cyB0aGUgYXZlcmFnZSBpbnNwZWN0aW9ucyBzY29yZSBmb3IgZWFjaCB6aXBjb2RlIGFyZWEuIEVhY2ggemlwY29kZSdzIGNvbG9yIGlzIGRldGVybWluZWQgYnkgaXRzIGF2ZXJhZ2UgaW5zcGVjdGlvbiBzY29yZSdzIHByb3hpbWl0eSB0byB0aGUgZ3JhbmQgYXZlcmFnZSBmb3IgdGhlIHllYXIocykgc2VsZWN0ZWQgaW4gdGhlIGZpbHRlci4gIFRoaXMgaXMgZG9uZSB1c2luZyBhIGNhbGN1bGF0ZWQgZmllbGQsIGFuZCB3aWxsIGJlIHJlY2FsY3VsYXRlZCBhY2NvcmRpbmcgdGhlIHRoZSBkYXRhIHNlbGVjdGVkIGluIHRoZSBZZWFyIGZpbHRlci4gIElmIGFycml2aW5nIGF0IHRoaXMgbWFwIGJ5IGNsaWNraW5nIG9uIGVpdGhlciBvZiB0aGUgY3Jvc3N0YWJzLCB0aGUgemlwIGNvZGVzIHdpbGwgZGlzcGxheSB0aGUgZGlmZmVyZW5jZSBmcm9tIHRoZSBncmFuZCBhdmVyYWdlIG9mIHRoZSBzZWxlY3RlZCB5ZWFyLgoKPGNlbnRlcj4hW1RhYmxlYXU6IE1hcCBvZiBBdmVyYWdlIEluc3BlY3Rpb24gU2NvcmVzXSguLi8wMyBWaXN1YWxpemF0aW9ucy9Dcm9zc3RhYkluc3BlY3Rpb25TY29yZU1hcC5wbmcpPC9jZW50ZXI+CgpJdCBpcyBhZ2FpbiBldmlkZW50IHRoYXQgYXZlcmFnZSBzY29yZXMgYXJlIHJlbGF0aXZlbHkgaGlnaCBhY3Jvc3MgZWFjaCBhcmVhLiAKCiMjIypBdmVyYWdlIFNjb3JlIGJ5IFllYXIqClRoaXMgaGlnaGx5IGNvbXByZWhlbnNpdmUgdmlzdWFsaXphdGlvbiBzaG93cyB1cyB0aHJlZSBtYWluIHBpZWNlcyBvZiBpbmZvcm1hdGlvbjogYXZlcmFnZSBzY29yZSwgbWluaW11bSBzY29yZSwgYW5kIHNhZmV0eSBpbmRleC4gQXMgaGFzIGJlZW4gcHJldmlvdXNseSBub3RlZCwgYXZlcmFnZSBzY29yZXMgYXJlIHJlbGF0aXZlbHkgaGlnaCBpbiBlYWNoIHppcGNvZGUuIE1pbnVtdW0gc2NvcmVzIGNhbiBiZSBxdWl0ZSBsb3cgKG9uZSBvZiB0aGUgbG93ZXN0IHNjb3JlcyBpcyAzNiksIGJ1dCB0aGVzZSBhcmUgZmV3IGFuZCBmYXIgYmV0d2Vlbi4KCjxjZW50ZXI+IVtUYWJsZWF1OiBBdmVyYWdlIFNjb3JlIGJ5IFllYXJdKC4uLzAzIFZpc3VhbGl6YXRpb25zL0Nyb3NzdGFiU2NvcmVzYnlZZWFyLnBuZyk8L2NlbnRlcj4KClRoaXMgY3Jvc3N0YWIgaXMgYWxzbyBjb2xvcmVkIGJ5IGEgU2FmZXR5IEluZGV4LiAgVGhpcyBLUEkgaXMgYmFzZWQgaW4gYSBjYWxjdWxhdGVkIGZpZWxkIHRoYXQgYWNjb3VudHMgZm9yIHRoZSBhdmVyYWdlIHNjb3JlIGFuZCBtaW5pbXVtIHNjb3JlIGZvciBhIGdpdmVuIHppcCBjb2RlIGluIGEgZ2l2ZW4geWVhciwgdGhlbiBwYXJhbWV0ZXJpemVkIGludG8gTG93LCBNZWRpdW0sIGFuZCBIaWdoIHJhbmtpbmdzLiAgVGhlIGJyZWFrIHBvaW50IGZvciBlYWNoIG9mIHRoZXNlIGdyb3VwaW5ncyBjYW4gYmUgYWRqdXN0ZWQgdXNpbmcgdGhlIHNsaWRlcnMgdG8gdGhlIHJpZ2h0IG9mIHRoZSBjcm9zc3RhYi4gIAoKIyMqKkJhcmNoYXJ0LXJlbGF0ZWQgVmlzdWFsaXphdGlvbnMgdXNpbmcgVGFibGVhdSoqCgoKIyMjKkNhcE1ldHJvIFN0b3BzIGJ5IFppcGNvZGUgYXMgdGhleSBSZWxhdGUgdG8gUmVzdGF1cmFudCBEZW5zaXR5KgpIZXJlIHdlIHNlZSB2aXN1YWxpemVkIHRoZSBudW1iZXIgb2YgYnVzIHN0b3BzIHBlciB6aXBjb2RlLCBjb2xvcmVkIGJ5IHRoZSBudW1iZXIgb2YgcmVzdGF1cmFudHMgaW4gdGhhdCB6aXBjb2RlLiBUaGlzIHZpc3VhbGl6YXRpb24gYWxzbyBzaG93cyBhbiBhdmVyYWdlIGxpbmUgZm9yIHRoZSBhdmVyYWdlIG51bWJlciBvZiBzdG9wcy4gQXMgaXMgZXZpZGVudCwgdGhlIHppcGNvZGVzIHdpdGggdGhlIGRhcmtlc3QgYmFycyAodGhvc2Ugd2l0aCB0aGUgaGlnaGVzdCByZXN0dWFyYW50IGRlbnNpdHkpLCBhbG1vc3QgYWx3YXlzIHN1cnBhc3MgdGhlIGF2ZXJhZ2UgbGluZSwgYnV0IGFsc28gZ2VuZXJhbGx5IGdyZWF0bHkgc3VycGFzcyBpdC4gVGhpcyBpcyBpbnRlcmVzdGluZyBiZWNhdXNlIGl0IHN1Z2dlc3RzIHRoYXQsIGluIGdlbmVyYWwsIHppcGNvZGVzIHdpdGggYSBoaWdoZXIgdGhhbiBhdmVyYWdlIG51bWJlciBvZiBidXMgc3RvcHMgYWxzbyBoYXZlIGEgaGlnaCByZXN0dWFyYW50IGRlbnNpdHkuCgo8Y2VudGVyPiFbVGFibGVhdTogU3RvcHMgYnkgWmlwY29kZV0oLi4vMDMgVmlzdWFsaXphdGlvbnMvVEJhcjFBLnBuZyk8L2NlbnRlcj4KPGNlbnRlcj4hW1RhYmxlYXU6IFN0b3BzIGJ5IFppcGNvZGUsIEhpZ2ggUmVzdGF1cmFudCBEZW5zaXR5XSguLi8wMyBWaXN1YWxpemF0aW9ucy9UQmFyMUIucG5nKTwvY2VudGVyPgoKSW4gVGFibGVhdSwgdGhpcyB2aXN1YWxpemF0aW9uIGFsc28gYWxsb3dzIHlvdSB0byBhZGp1c3Qgd2hpY2ggemlwY29kZXMgYXJlIGRpc3BsYXllZCBiYXNlZCBvbiBhIG1pbmltdW0gYW1vdW50IG9mIHJlc3RhdXJhbnRzLCBhbmQgYWxzbyBiYXNlZCBvbiB3aGV0aGVyIHRoZSB6aXBjb2RlcyBhcmUgYWJvdmUgb3IgYmVsb3cgdGhpcyBtaW5pbXVtLgoKIyMjKkZvcmVpZ24gUG9wdWxhdGlvbiB2cy4gUmVzdGF1cmFudCBEZW5zaXR5KgpIZXJlIHdlIGZpbmQgYSB2aXN1YWxpemF0aW9uIHRoYXQgc2hvd2Nhc2VzIGZvcmVpZ24gcG9wdWxhdGlvbiBieSB6aXBjb2RlLCBhbmQgaXMgY29sb3JlZCB0byByZWZsZWN0IHRoZSByZXN0YXVyYW50IGRlbnNpdHkgb2YgZWFjaCB6aXBjb2RlLiBJbiBUYWJsZWF1LCB5b3UgYXJlIGFsc28gYWJsZSB0byB0b2dnbGUgYmFjayBhbmQgZm9ydGggYmV0d2VlbiBhIGhpZ2hlciB0aGFuIGF2ZXJhZ2UsIG9yIGFuIGF0L2JlbG93IGF2ZXJhZ2UgZm9yZWlnbiBwb3B1bGF0aW9uLgoKPGNlbnRlcj4hW1RhYmxlYXU6IFJlc3RhdXJhbnQgRGVuc2l0eSwgTG93IEZvcmVpZ24gUG9wdWxhdGlvbl0oLi4vMDMgVmlzdWFsaXphdGlvbnMvVEJhcjJBLnBuZyk8L2NlbnRlcj4KPGNlbnRlcj4hW1RhYmxlYXU6IFJlc3RhdXJhbnQgRGVuc2l0eSwgSGlnaCBGb3JlaWduIFBvcHVsYXRpb25dKC4uLzAzIFZpc3VhbGl6YXRpb25zL1RCYXIyQi5wbmcpPC9jZW50ZXI+CgpGcm9tIHRoaXMgYmFyY2hhcnQsIGl0IHdvdWxkIHNlZW0gdGhhdCBoaWdoZXIgdGhhbiBhdmVyYWdlIGZvcmVpZ24gcG9wdWxhdGVkIHppcGNvZGVzIGRvbid0IG5lY2Vzc2FyaWx5IGhhdmUgYSBoaWdoZXIgcmVzdGF1cmFudCBkZW5zaXR5LiBPdmVyYWxsLCBpdCBhcHBlYXJzIHRoYXQgcmVzdGF1cmFudCBkZW5zaXR5IGlzIHByZXR0eSBldmVuIGFjcm9zcyBsZXZlbHMgb2YgZm9yZWlnbi1ib3JuIHBvcHVsYXRpb24gKGkuZS4gdGhlcmUgYXJlIHJlbGF0aXZlbHkgc2ltaWxhciBudW1iZXJzIG9mIGhpZ2ggcmVzdGF1cmFudCBkZW5zaXR5IHppcGNvZGVzIGluIGJvdGggY2F0ZWdvcmllcykuIFRoaXMgaXMgaW50ZXJlc3RpbmcgYmVjYXVzZSBpdCBzdWdnZXN0cyB0aGF0IHJlc3RhdXJhbnQgZGVuc2l0eSBtYXkgYmUgZmFpcmx5IGluZGVwZW5kZW50IG9mIGZvcmVpZ24tIG9yIG5hdGl2ZS1ib3JuIHBvcHVsYXRpb24gc3RhdHVzLgoKIyMjKlN0b3AgdG8gUmVzdHVhcmFudCBSYXRpb3MgcGVyIFppcGNvZGUgYnkgTmF0aXZpdHkqClRoaXMgdmlzdWFsaXphdGlvbiBzaG93cyB0aGUgcG9wdWxhdGlvbnMgb2YgTmF0aXZlLCBOYXR1cmFsaXplZCwgYW5kIE5vbi1DaXRpdHplbiBpbmhhYml0YW50cyBmb3IgZWFjaCB6aXBjb2RlLiBGdXJ0aGVyLCB0aGVzZSBiYXJjaGFydHMgYXJlIGNvbG9yZWQgYnkgdGhlIHJlc3RhdXJhbnQgdG8gc3RvcCByYXRpbyAoZGFya2VyIHB1cnBsZSBpbmRpY2F0ZXMgYSBoaWdoZXIgcmF0aW8pLiBUaGUgaGlnaGVzdCByYXRpb3MgYXJlIGJldHdlZW4gNzg3MjEgYW5kIDc4NzI0LiAKCjxjZW50ZXI+IVtUYWJsZWF1OiBTdG9wcyB0byBSZXN0YXVyYW50cyBieSBOYXRpdml0eV0oLi4vMDMgVmlzdWFsaXphdGlvbnMvVEJhcjMucG5nKTwvY2VudGVyPgoKSW50ZXJlc3RpbmdseSwgdGhlIHBvcHVsYXRpb24gb2YgbmF0aXZlLCBuYXR1cmFsaXplZCwgYW5kIG5vbi1jaXRpemVuIHBlb3BsZXMgaXMgcXVpdGUgdmFyaWFibGUgYWNyb3NzIHppcGNvZGVzLiBBbm90aGVyIGludGVyZXN0aW5nIHBvaW50IGlzIHRoYXQgZm9yIGFsbCB0aHJlZSBjYXRlZ29yaWVzLCB0aGUgaGlnaGVzdCByYXRpb3MgYXJlIG5vdCBjb3JyZWxhdGVkIHdpdGggdGhlIGhpZ2hlc3QgcG9wdWxhdGlvbnMuIFRoaXMsIG9mIGNvdXJzZSwgc2VlbXMgbm9uLWludHVpdGl2ZSwgYW5kIG1heSBiZSBhbiBhcmVhIGZvciBmdXR1cmUgaW5xdWlyeS4KCiMjKipWaXN1YWxpemF0aW9ucyB1c2luZyBTaGlueSBpbiBSKioKVGhlIHNjcmVlbnNob3RzIGFuZCBkZXNjcmlwdGlvbnMgYmVsb3cgYXJlIGJhc2VkIG9uIG91ciBpbnRlcmFjdGl2ZSB2aXN1YWxpemF0aW9uIGFwcCwgYWNjZXNzaWJsZSBhdCBodHRwczovL2t2YXVnaG4uc2hpbnlhcHBzLmlvL3Jlc3RhdXJhbnRfaW5zcGVjdGlvbi8uCgojIyMqKkJveHBsb3QgVmlzdWFsaXphdGlvbiB1c2luZyBTaGlueSBpbiBSKioKT25lIGxvdyBzY29yZSBkb2VzIG5vdCBpbmRpY2F0ZSBhIHN5c3RlbWljIHByb2JsZW0gd2l0aCBhIHJlc3RhdXJhbnQncyBjbGVhbmxpbmVzczsgYmVmb3JlIGp1ZGdpbmcgYSByZXN0YXVyYW50IHdpdGggYSBsb3cgc2NvcmUsIGl0IGJlaG9vdmVzIHVzIHRvIGNvbnNpZGVyIHRoZSBvdGhlciBzY29yZXMgaXQgaGFzIHJlY2VpdmVkLiAgVGhpcyBib3hwbG90IGFsbG93cyB0aGUgdXNlciB0byBkbyBqdXN0IHRoYXQuICBGaXJzdCBzZWxlY3QgYSBjdXRvb2YgcG9pbnQgZm9yIHNjb3JlcywgdGhlbiBjaG9vc2UgYSB6aXBjb2RlIHRvIHNlZSBhbGwgcmVzdGF1cmFudHMgdGhhdCBoYXZlIHNjb3JlZCBiZWxvdyB0aGF0IGxldmVsIGF0IGxlYXN0IG9uZS4gIEVhY2ggcmVzdGF1cmFudCdzIHNjb3JlcyB3aWxsIGRpc3BsYXksIGdpdmluZyB0aGUgdXNlciBhbiBpZGVhIG9mIHdoZXRoZXIgdGhlIGxvdyBzY29yZSB3YXMgYSBmbHVrZSBvciBhIHNpZ24gb2YgcHJvYmxlbXMuCgojIyMqKkhpc3RvZ3JhbSBWaXN1YWxpemF0aW9uIHVzaW5nIFNoaW55IGluIFIqKgoKIyMjKipTY2F0dGVycGxvdCBWaXN1YWxpemF0aW9uIHVzaW5nIFNoaW55IGluIFIqKgoKCiMjIyoqQ3Jvc3N0YWIgVmlzdWFsaXphdGlvbnMgdXNpbmcgU2hpbnkgaW4gUioqCkNsaWNrIGhlcmUgdG8gYmUgdGFrZW4gdG8gb3VyIHB1Ymxpc2hlZCBTaGlueSBhcHA6IGh0dHBzOi8va3ZhdWdobi5zaGlueWFwcHMuaW8vcmVzdGF1cmFudF9pbnNwZWN0aW9uLwoKIyMjKlNhZmV0eSBJbmRleCoKVGhpcyB2aXN1YWxpemF0aW9uIHN0YXJ0cyB3aXRoIGEgc29tZXdoYXQtYXJiaXRyYXJ5IEtQSSwgdGhlICJTYWZldHkgSW5kZXgsIiB0aGF0IHRha2VzIGludG8gYWNjb3VudCBib3RoIHRoZSBhdmVyYWdlIHNjb3JlIGFuZCB0aGUgbG93ZXN0IGluc3BlY3Rpb24gc2NvcmUgcmVjZWl2ZWQgZm9yIGEgZ2l2ZW4gemlwIGNvZGUgaW4gYSBnaXZlbiB5ZWFyLiAgQSBoaWdoIFNhZmV0eSBJbmRleCBpbmRpY2F0ZXMgYm90aCBhIGhpZ2ggYXZlcmFnZSBzY29yZSBhbmQgYSBoaWdoIG1pbmltdW0gc2NvcmUuICBTZXQgdGhlIHBhcmFtZXRlcnMgaG93ZXZlciB5b3UgbGlrZSAoMyBhbmQgOCBhcmUgcmVhc29uYWJsZSBkZWZhdWx0cykgYW5kIGNoZWNrIHRoZSBjcm9zc3RhYiB0byBzZWUgZWFjaCB6aXAgY29kZSdzIHJhdGluZ3Mgb3ZlciB0aGUgZm91ci15ZWFyIHBlcmlvZC4KCjxjZW50ZXI+IVtTaGlueTogU2FmZXR5IEluZGV4IERhdGFdKC4uLzAzIFZpc3VhbGl6YXRpb25zL1NDcm9zczFBLnBuZyk8L2NlbnRlcj4gCjxjZW50ZXI+IVtTaGlueTogU2FmZXR5IEluZGV4IENyb3NzdGFiXSguLi8wMyBWaXN1YWxpemF0aW9ucy9TQ3Jvc3MxQi5wbmcpPC9jZW50ZXI+CgojIyMqTG93ZXN0IEluc3BlY3Rpb24gU2NvcmVzKgpUaGlzIHZpc3VhbGl6YXRpb24gYWxsb3dzIHRoZSB1c2VyIHRvIHNldCBhbiBhcmJpdHJhcnkgY3V0b2ZmIHBvaW50IGFzIGFuIGFpZCBmb3IgaWRlbnRpZnlpbmcgbG93IGluc3BlY3Rpb24gc2NvcmVzLiAgVGhlIGRlZmF1bHQgdmFsdWUsIDcwLCBpcyB0aGUgY3V0b2ZmIGZvciByZXN0YXVyYW50IGluc3BlY3Rpb25zOyBsb3dlciBzY29yZXMgd2lsbCB0cmlnZ2VyIGEgcmVpbnNwZWN0aW9uLiAgQWZ0ZXIgc2VsZWN0aW5nIGEgcGFyYW1ldGVyIHVzaW5nIHRoZSBzbGlkZXIgYW5kIHJlcXVlc3RpbmcgZGF0YSwgdGhlIHVzZXIgY2FuIHNlbGVjdCB0aGUgIkNyb3NzdGFiIiB0YWIgdG8gc2VlIHdoaWNoIHppcCBjb2RlcyBhbmQgeWVhcnMgaGFkIHVuYWNjZXB0YWJseSBsb3cgaW5zcGVjdGlvbiBzY29yZXMuCgo8Y2VudGVyPiFbU2hpbnk6IExvd2VzdCBJbnNwZWN0aW9uIFNjb3JlcyBEYXRhXSguLi8wMyBWaXN1YWxpemF0aW9ucy9TQ3Jvc3MyQS5wbmcpPC9jZW50ZXI+IAo8Y2VudGVyPiFbU2hpbnk6IExvd2VzdCBJbnNwZWN0aW9uIFNjb3JlcyBDcm9zc3RhYl0oLi4vMDMgVmlzdWFsaXphdGlvbnMvU0Nyb3NzMkIucG5nKTwvY2VudGVyPgoKIyMjKlBlb3BsZSBwZXIgUmVzdGF1cmFudCoKQXVzdGluIGlzIGEgZmFzdC1ncm93aW5nIGNpdHksIGFuZCBvdXIgcmVzdGF1cmFudCBzY2VuZSBpcyBjdXJyZW50bHkgYm9vbWluZyBhcyB3ZWxsLiAgVGhpcyB2aXN1YWxpemF0aW9uIGFsbG93cyBhIHVzZXIgdG8gc2VlIHdoZXJlIHRoZSBkZW5zaXR5IG9mIHJlc3RhdXJhbnRzIGNvbXBhcmVkIHRvIHBvcHVsYXRpb24gaXMgaGlnaGVzdC4gIFVzaW5nIGEgcHVibGljIHBvcHVsYXRpb24gZGF0YXNldCBnZW5lcmF0ZWQgYnkgdGhlIFVTIENlbnN1cywgd2UgY2FuIGZpbmQgdGhlIG51bWJlciBvZiBwZW9wbGUgcGVyIHJlc3RhdXJhbnQgaW4gYSBnaXZlbiB6aXAgY29kZTsgYXMgbW9yZSByZXN0YXVyYW50cyBhcmUgYWRkZWQgKG9yIGZhaWwpLCB0aGUgcGVvcGxlLXBlci1yZXN0YXVyYW50IG51bWJlciBjaGFuZ2VzLiAgVGhlIGRlZmF1bHQgdmFsdWVzIGhpZ2hsaWdodCB0aGUgZGVuc2l0eSBvZiByZXN0YXVyYW50cyBpbiA3ODcwMSwgd2hpY2ggaXMgZG93bnRvd24gQXVzdGluLgoKPGNlbnRlcj4hW1NoaW55OiBQZW9wbGUgcGVyIFJlc3RhdXJhbnQgRGF0YV0oLi4vMDMgVmlzdWFsaXphdGlvbnMvU0Nyb3NzM0EucG5nKTwvY2VudGVyPiAKPGNlbnRlcj4hW1NoaW55OiBQZW9wbGUgcGVyIFJlc3RhdXJhbnQgQ3Jvc3N0YWJdKC4uLzAzIFZpc3VhbGl6YXRpb25zL1NDcm9zczNCLnBuZyk8L2NlbnRlcj4KCiMjKipCYXJjaGFydCBWaXN1YWxpemF0aW9ucyB1c2luZyBTaGlueSBpbiBSKioKVGhlc2UgdmlzdWFsaXphdGlvbnMgYXJlIGFsc28gYWNjZXNzaWJsZSBhdCBodHRwczovL2t2YXVnaG4uc2hpbnlhcHBzLmlvL3Jlc3RhdXJhbnRfaW5zcGVjdGlvbi8KCiMjIypTY29yZXMgYnkgWmlwIENvZGUqCkJhcmNoYXJ0cyBjYW4gYmUgYSBnb29kIHdheSB0byBxdWlja2x5IGlkZW50aWZ5IHRyZW5kcyB2aXN1YWxseS4gIEluIHRoaXMgdmlzdWFsaXphdGlvbiwgdGhlIHVzZXIgY2FuIGNyZWF0ZSBhIHNldCBvZiB6aXAgY29kZXMgb2YgaW50ZXJlc3QsIHRoZW4gc2VlIGVhY2ggemlwY29kZSdzIGF2ZXJhZ2Ugc2NvcmUgcGVyIHllYXIgb3ZlciB0aGUgdGhyZWUgb3IgZm91ciB5ZWFycyBjb250YWluZWQgaW4gdGhlIGRhdGFzZXQuCgo8Y2VudGVyPiFbU2hpbnk6IFNjb3JlcyBieSBaaXAgQ29kZSBEYXRhXSguLi8wMyBWaXN1YWxpemF0aW9ucy9TQmFyMUEucG5nKTwvY2VudGVyPiAKPGNlbnRlcj4hW1NoaW55OiBTY29yZXMgYnkgWmlwIENvZGUgQmFyIENoYXJ0XSguLi8wMyBWaXN1YWxpemF0aW9ucy9TQmFyMUIucG5nKTwvY2VudGVyPgoKIyMjKlRyYW5zaXQgc3RvcHMgYW5kIHJlc3RhdXJhbnQgZGVuc2l0eSoKQ2FwaXRhbCBNZXRybywgdGhlIEF1c3Rpbi1hcmVhIHRyYW5zaXQgc2VydmljZSwgaGFzIG1hZGUgaXRzIGRhdGEgZnJlZWx5IGF2YWlsYWJsZSBmb3IgcHVibGljIGRvd25sb2FkLiAgQnkgaW1wb3J0aW5nIHRoaXMgZGF0YSBpbnRvIGdlb2dyYXBoaWMgaW5mb3JtYXRpb24gc29mdHdhcmUgKEFyY0dJUykgYW5kIG92ZXJsYXlpbmcgdGhlIGNvb3JkaW5hdGVzIG9mIHRyYW5zaXQgc3RvcHMgb24gYSBzaGFwZWZpbGUgb2YgcmVnaW9uYWwgemlwIGNvZGVzLCB3ZSB3ZXJlIGFibGUgdG8gY291bnQgdGhlIG51bWJlciBvZiB0cmFuc2l0IHN0b3BzIHBlciB6aXAgY29kZS4gIEluIHRoaXMgYmFyIGNoYXJ0LCB3ZSdyZSBleGFtaW5pbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRyYW5zaXQgZGVuc2l0eSBhbmQgcmVzdGF1cmFudCBkZW5zaXR5LiAgVXNlIHRoZSBzbGlkZXIgdG8gc2VsZWN0IHppcCBjb2RlcyB3aXRoIG1vcmUgdGhhbiB0aGUgbWluaW11bSBudW1iZXIgb2YgdHJhbnNpdCBzdG9wcywgdGhlbiBjb21wYXJlIHRoZSBudW1iZXIgb2YgcmVzdGF1cmFudHMgaW4gdGhlc2UgemlwIGNvZGVzIHRvIHRoZSBhdmVyYWdlIG51bWJlciBvZiByZXN0YXVyYW50cyBwZXIgemlwIGNvZGUgdGhyb3VnaG91dCB0aGUgcmVnaW9uLiAgVGhlIGJsdWUgbGluZSBpcyB0aGUgY2FsY3VsYXRlZCBhdmVyYWdlIGZvciBhbGwgb2YgdGhlIHNlbGVjdGVkIHppcCBjb2RlcywgYW5kIHRoZSByZWQgaXMgdGhlIGdyYW5kIGF2ZXJhZ2UgZm9yIGFsbCBvZiB0aGUgemlwY29kZXMgaW4gdGhlIEdyZWF0ZXIgQXVzdGluIGFyZWEuCgo8Y2VudGVyPiFbU2hpbnk6IFJlc3RhdXJhbnQgRGVuc2l0eSBhbmQgVHJhbnNpdCBTdG9wcyBEYXRhXSguLi8wMyBWaXN1YWxpemF0aW9ucy9TQmFyMkEucG5nKTwvY2VudGVyPiAKPGNlbnRlcj4hW1NoaW55OiBSZXN0YXVyYW50IERlbnNpdHkgYW5kIFRyYW5zaXQgU3RvcHMgQmFyIENoYXJ0XSguLi8wMyBWaXN1YWxpemF0aW9ucy9TQmFyMkIucG5nKTwvY2VudGVyPgoKIyMjKk5vbm5hdGl2ZSByZXNpZGVudHMgYW5kIHJlc3RhdXJhbnQgZGVuc2l0eSoKV291bGQgd2UgZXhwZWN0IHppcCBjb2RlcyB3aXRoIGNvbXBhcmF0aXZlbHkgbGFyZ2UgbnVtYmVycyBvZiBub25uYXRpdmUgKG5hdHVyYWxpemVkLWNpdGl6ZW4gb3Igbm9uY2l0aXplbikgcmVzaWRlbnRzIHRvIGhhdmUgbW9yZSBvciBmZXdlciByZXN0YXVyYW50cywgb24gYXZlcmFnZSwgdGhhbiB6aXAgY29kZXMgd2l0aCBsb3dlciBwZXJjZW50YWdlcyBvZiBub25uYXRpdmUgcmVzaWRlbnRzPyAgVGhpcyBiYXJjaGFydCBhbGxvd3MgdGhlIHVzZXIgdG8gc2VsZWN0IGEgbWluaW11bSBwZXJjZW50YWdlIG9mIG5vbm5hdGl2ZSByZXNpZGVudHMgcGVyIHppcCBjb2RlLCB0aGVuIHNob3dzIHRoZSBudW1iZXIgb2YgcmVzdGF1cmFudHMgaW4gdGhhdCB6aXAgY29kZSBhbmQgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIHJlc3RhdXJhbnRzIHBlciB6aXAgY29kZSBmb3IgYWxsIG9mIHRoZSBxdWFsaWZ5aW5nIHppcCBjb2Rlcy4gIFRoaXMgYXZlcmFnZSBjYW4gYmUgY29tcGFyZWQgdG8gdGhlIGdyYW5kIGF2ZXJhZ2UgdGhyb3VnaG91dCB0aGUgZ3JlYXRlciBBdXN0aW4gYXJlYSwgc2hvd24gaW4gcmVkLgoKPGNlbnRlcj4hW1NoaW55OiBSZXN0YXVyYW50IERlbnNpdHkgYW5kIE5vbm5hdGl2ZSBSZXNpZGVudHMgRGF0YV0oLi4vMDMgVmlzdWFsaXphdGlvbnMvU0JhcjNBLnBuZyk8L2NlbnRlcj4gCjxjZW50ZXI+IVtTaGlueTogUmVzdGF1cmFudCBEZW5zaXR5IGFuZCBOb25uYXRpdmUgUmVzaWRlbnRzIEJhciBDaGFydF0oLi4vMDMgVmlzdWFsaXphdGlvbnMvU0JhcjNCLnBuZyk8L2NlbnRlcj4K